﻿//
//  YHClassObject.h
//  ThunderWarriors
//
//  Created by hlp on 12-12-28.
//
//

#ifndef ThunderWarriors_YHClassFactory_h
#define ThunderWarriors_YHClassFactory_h
#include "iostream"
#include "stdio.h"
#include <map>
#include <string>
using namespace std;

typedef void* (*CLASS_SELECTOR)(void);
typedef void* (*DELETE_CLASS_SELECTOR)(void*);
typedef void (*SET_CLASS_SELECTOR)(void*lhs, void* rhs);

#define class_selector(__SELECTOR) (CLASS_SELECTOR)(& __SELECTOR)
#define delete_class_selector(__SELECTOR) (DELETE_CLASS_SELECTOR)(& __SELECTOR)
#define set_class_selector(__SELECTOR) (SET_CLASS_SELECTOR)(& __SELECTOR)
class YHClassObject {
public:
    string m_className;
    CLASS_SELECTOR m_classSelector;
    DELETE_CLASS_SELECTOR m_deleteDlassSelector;
    SET_CLASS_SELECTOR m_setClassSelector;
    YHClassObject();
    YHClassObject(string className, CLASS_SELECTOR classSelector, DELETE_CLASS_SELECTOR deleteClassSelector, SET_CLASS_SELECTOR setClassSelector);
};

class YHClassFactory{
public:
    static YHClassFactory* sharedClassFactory();
    YHClassFactory();
    ~ YHClassFactory();
    virtual void init();
    //根据类名取得该类的实例
    void* getClasstByName(string className);
    //根据类名称和类的静态创建方法函数来注册
    void registerClass(string className, CLASS_SELECTOR classSelector, DELETE_CLASS_SELECTOR deleteClassSelector, SET_CLASS_SELECTOR setClassSelector);
    //根据类名称和类的静态创建方法函数来注册
    void registerClass(char* className, CLASS_SELECTOR classSelector, DELETE_CLASS_SELECTOR deleteClassSelector, SET_CLASS_SELECTOR setClassSelector);
    //根据YHCLassObject来注册
    void registerClass(YHClassObject classObject);
    //删除类的实例, instance是类实例
    void deleteClassByName(string className, void* instance);
    inline map<string, YHClassObject>& getClassObjects(){return m_mapStringClassObjects;}
private:
    //map保存类的名字和创建该类的函数指针
    map<string, YHClassObject> m_mapStringClassObjects;
    static YHClassFactory* m_shared_ClassFactory;
};

//两个#号，比如"createClass##__ClassName__"的作用是起链接字符的作用
#define DECLARE_CREATE_CLASS(__ClassName__) \
static __ClassName__* createClass##__ClassName__();\
static void deleteClass##__ClassName__(void* pInstance);\
static void setClass##__ClassName__(void* lhs, void* rhs);\
static YHClassObject m_classObject;

//一个‘#__ClassName'的作用是将__ClassName__作为字符串处理
#define IMPLEMENT_CREATE_CLASS(__ClassName__)\
YHClassObject __ClassName__::m_classObject = \
YHClassObject(#__ClassName__, class_selector(__ClassName__::createClass##__ClassName__),\
                              delete_class_selector(__ClassName__::deleteClass##__ClassName__),\
                              set_class_selector(__ClassName__::setClass##__ClassName__));\
\
__ClassName__* __ClassName__::createClass##__ClassName__(){ \
    __ClassName__* pRet = new __ClassName__();\
    if (NULL != pRet){\
        pRet->autorelease();\
        return pRet;\
    }\
    return NULL;\
}\
\
void __ClassName__::deleteClass##__ClassName__(void* pInstance){\
    __ClassName__* classInstance = (__ClassName__*) pInstance;\
    classInstance->~__ClassName__();\
}\
\
void __ClassName__::setClass##__ClassName__(void* lhs, void* rhs){ \
    __ClassName__* pLhs = (__ClassName__*)lhs;\
    __ClassName__* pRhs = (__ClassName__*)rhs;\
    *pLhs = *pRhs;\
}

//动态属性相关的宏
//动态属性声明，注意：如果使用了动态属性，那么必须在析构函数或者垃圾回收函数负责手动调用 RELEASE_DYNAMIC_PROPERTY(__ClassName__)
#define DECLARE_DYNAMIC_PROPERTY(__ClassName__) \
public:\
protected:  map<string,void*> m_dynamicPropertiesMap;\
public: inline void setDynamicPropertyByName(string class_type_name, string propertyName, void* pValue){ \
    map<string, void*>::iterator itProperty = m_dynamicPropertiesMap.find(propertyName);\
    map<string, YHClassObject>& classObjects = YHClassFactory::sharedClassFactory()->getClassObjects();\
    map<string, YHClassObject>::iterator itClass = classObjects.find(class_type_name);\
    if (itProperty != m_dynamicPropertiesMap.end() && itClass != classObjects.end()) {\
        YHClassObject classObject = itClass->second;\
        SET_CLASS_SELECTOR funSetClass = classObject.m_setClassSelector;\
        (*funSetClass)(itProperty->second, pValue);\
    }\
}\
\
public: inline void* getDynamicPropertyByName(string propertyName){ \
    void* pRet = NULL;\
    map<string, void*>::iterator itProperty = m_dynamicPropertiesMap.find(propertyName);\
    if (itProperty != m_dynamicPropertiesMap.end()) {\
        pRet = itProperty->second;\
    }\
    return pRet;\
}\
\
public: inline void createDynamicPropertyByName(string className, string propertyName){ \
    void* pRet = YHClassFactory::sharedClassFactory()->getClasstByName(className);\
    if(pRet){ \
        m_dynamicPropertiesMap.insert( pair<string, void*>(propertyName, pRet));\
    }\
}

//释放类的动态属性，如果使用到了动态属性，那么在析构函数里面调用这个
#define RELEASE_DYNAMIC_PROPERTY(__ClassName__) \
    for(map<string,void*>::iterator it = m_dynamicPropertiesMap.begin(); it != m_dynamicPropertiesMap.end(); it ++){ \
        string className = it->first;\
        void* classInstance = it->second;\
        YHClassFactory::sharedClassFactory()->deleteClassByName(className, classInstance);\
    }


//静态属性相关的宏
#define PROPERTY_SYHTHESIZE(varType, varName, funName)\
protected: varType varName;\
public: virtual varType get##funName(void) const {return varName;}\
public: virtual void set##funName(varType var){varName = var;}\
public: virtual void* getProperty##funName(void) {return &varName;}\
public: virtual void setProperty##funName(void* pVar){varName = *((varType*)pVar);}

#define DECLARE_PROPERTY(__ClassName__) \
public:\
typedef void (__ClassName__::*SetProperty)(void* pValue);\
typedef void* (__ClassName__::*GetProperty)(void);\
protected:  map<string,SetProperty> m_setPropertyMap;\
protected:  map<string,GetProperty> m_getPropertyMap;\
\
public: inline void setPropertyByName(string propertyName, void* pValue){ \
    map<string, SetProperty>::iterator it = m_setPropertyMap.find(propertyName);\
    if (it != m_setPropertyMap.end()) {\
        SetProperty funSetProperty = it->second;\
        (this->*funSetProperty)(pValue);\
    }\
}\
\
public: inline void* getPropertyByName(string propertyName){ \
        void* pRet = NULL;\
        map<string, GetProperty>::iterator it = m_getPropertyMap.find(propertyName);\
        if (it != m_getPropertyMap.end()) {\
            GetProperty funGetProperty = it->second;\
            pRet = (this->*funGetProperty)();\
        }\
        return pRet;\
}\
\
public: virtual void registerProperty();


#define REGISTER_PROPERTY() registerProperty();


#define BEGIN_PROPERTY(__ClassName__)\
void __ClassName__::registerProperty(){


#define ADD_PROPERTY(__ClassName__, __PropertyName__, __funName__) \
m_setPropertyMap.insert(pair<string,SetProperty>(__PropertyName__, \
                 &__ClassName__::setProperty##__funName__));\
m_getPropertyMap.insert(pair<string,__ClassName__::GetProperty>(__PropertyName__, \
                 &__ClassName__::getProperty##__funName__));


#define END_PROPERTY() }

#endif/*ThunderWarriors_YHClassFactory_h*/
